package com.molichuxing.services.business.service.impl;

import com.molichuxing.framework.exception.BizException;
import com.molichuxing.services.business.convertor.Convert;
import com.molichuxing.services.business.dto.request.create.OrderEnterpriseDeliveryCreateBizDto;
import com.molichuxing.services.business.dto.request.create.OrderEnterpriseReturnCreateBizDto;
import com.molichuxing.services.business.service.EnterpriseCarHandoverBizService;
import com.molichuxing.services.business.service.EnterpriseScheduleBizService;
import com.molichuxing.services.exception.OrderExceptionCodeEnum;
import com.molichuxing.services.infrastructure.dto.request.create.EnterpriseCarHandoverCreateDto;
import com.molichuxing.services.infrastructure.dto.request.modify.EnterpriseCarModifyDto;
import com.molichuxing.services.infrastructure.dto.response.EnterpriseCarDto;
import com.molichuxing.services.infrastructure.dto.response.OrderEnterpriseDto;
import com.molichuxing.services.infrastructure.service.EnterpriseCarHandoverService;
import com.molichuxing.services.infrastructure.service.EnterpriseCarService;
import com.molichuxing.services.infrastructure.service.EnterpriseStateFlowService;
import com.molichuxing.services.infrastructure.service.OrderEnterpriseService;
import com.molichuxing.services.property.EnterpriseCarHandoverTypeEnum;
import com.molichuxing.services.property.EnterpriseCarStateEnum;
import com.molichuxing.services.property.EnterpriseStateEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * 企业订单排期服务
 *
 * @author zhaopenghui
 * @date 2020年6月4日
 */
@Service("enterpriseCarHandoverBizService")
public class EnterpriseCarHandoverBizServiceImpl implements EnterpriseCarHandoverBizService {
    private static final Logger logger = LoggerFactory.getLogger(EnterpriseCarHandoverBizServiceImpl.class);

    @Resource
    private OrderEnterpriseService orderEnterpriseService;

    @Resource
    private EnterpriseCarHandoverService enterpriseCarHandoverService;

    @Resource
    private EnterpriseCarService enterpriseCarService;

    @Resource
    private EnterpriseScheduleBizService enterpriseScheduleBizService;

    @Resource
    private EnterpriseStateFlowService enterpriseStateFlowService;

    /**
     * 退租
     *
     * @param createBizDto
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Boolean createOrderEnterpriseReturn(OrderEnterpriseReturnCreateBizDto createBizDto) {
        Long orderCode = createBizDto.getOrderCode();
        Integer carId = createBizDto.getCarId();
        String vin = createBizDto.getVin();
        OrderEnterpriseDto orderEnterpriseDto = orderEnterpriseService.getEnterprise(orderCode);
        if (null == orderEnterpriseDto) {
            logger.error("退租异常，订单({})不存在", orderCode);
            throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(),
                    "退租异常，订单(" + orderCode + ")不存在");
        }
        EnterpriseCarDto enterpriseCar = enterpriseCarService.getEnterpriseCar(orderCode, carId);
        if (null == enterpriseCar) {
            logger.error("退租异常，订单({})车辆({})不存在", orderCode, vin);
            throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(),
                    "退租异常，订单(" + orderCode + ")车辆(" + vin + ")不存在");
        } else if (null == enterpriseCar.getState() || EnterpriseCarStateEnum.LEASE.getValue() != enterpriseCar.getState()) {
            EnterpriseCarStateEnum state = EnterpriseCarStateEnum.getEnum(enterpriseCar.getState());
            logger.error("退租异常，订单({})车辆({})当前状态({})不可退租", orderCode,
                    vin, state);
            throw new BizException(OrderExceptionCodeEnum.STATUS_ERROR.getCode(),
                    "退租异常，订单(" + orderCode + ")车辆(" + vin + ")当前状态(" + state.getName() + ")不可退租");
        }

        // 新增订单交接信息
        EnterpriseCarHandoverCreateDto enterpriseCarHandoverCreateDto = Convert.toEnterpriseCarHandoverCreateDto(createBizDto, enterpriseCar);
        enterpriseCarHandoverCreateDto.setEnterpriseId(orderEnterpriseDto.getEnterpriseId());
        enterpriseCarHandoverCreateDto.setType(EnterpriseCarHandoverTypeEnum.RETURN.getValue());
        if (!enterpriseCarHandoverService.createCarhandover(enterpriseCarHandoverCreateDto)) {
            logger.error("退租异常，订单({})车辆({})新增订单车辆交接信息异常", orderCode, vin);
            throw new BizException("退租异常");
        }
        // 修改订单车辆信息
        EnterpriseCarModifyDto enterpriseCarModifyDto = Convert.toEnterpriseCarModifyDto(createBizDto, enterpriseCar);
        if (!enterpriseCarService.modifyReturn(enterpriseCarModifyDto)) {
            logger.error("退租异常，订单({})车辆({})修改订单车辆信息异常", orderCode, vin);
            throw new BizException("退租异常");
        }
        // 修改订单车辆排期信息
        if (!enterpriseScheduleBizService.modifyCarTermination(orderCode, carId)) {
            logger.error("退租异常，终止订单({})车辆({})车辆排期异常", orderCode, vin);
            throw new BizException("退租异常");
        }

        return true;
    }

    /**
     * 交车
     *
     * @param orderEnterpriseDeliveryCreateBizDto
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Boolean createOrderEnterpriseDelivery(OrderEnterpriseDeliveryCreateBizDto orderEnterpriseDeliveryCreateBizDto) {
        Long orderCode = orderEnterpriseDeliveryCreateBizDto.getOrderCode();
        Integer carId = orderEnterpriseDeliveryCreateBizDto.getCarId();
        String vin = orderEnterpriseDeliveryCreateBizDto.getVin();

        OrderEnterpriseDto orderEnterpriseDto = orderEnterpriseService.getEnterprise(orderCode);
        if (null == orderEnterpriseDto) {
            logger.error("交车异常，订单({})不存在", orderCode);
            throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(),
                    "交车异常，订单(" + orderCode + ")不存在");
        }

        EnterpriseCarDto enterpriseCar = enterpriseCarService.getEnterpriseCar(orderCode, carId);
        if (null == enterpriseCar) {
            logger.error("交车异常，订单({})车辆({})不存在", orderCode, vin);
            throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(),
                    "交车异常，订单(" + orderCode + ")车辆(" + vin + ")不存在");
        }

        Integer state = enterpriseCar.getState();
        if (null == state || EnterpriseCarStateEnum.UNDELIVERY.getValue() != state) {
            logger.error("交车异常，订单({})车辆({})当前状态({})不可交车", orderCode,
                    vin, EnterpriseCarStateEnum.getName(state));
            throw new BizException(OrderExceptionCodeEnum.STATUS_ERROR.getCode(),
                    "交车异常，订单(" + orderCode + ")车辆(" + vin + ")当前状态(" + EnterpriseCarStateEnum.getName(state) + ")不可交车");
        }

        //新增车辆交接
        EnterpriseCarHandoverCreateDto enterpriseCarHandoverCreateDto = Convert.toEnterpriseCarHandoverCreateDto(orderEnterpriseDeliveryCreateBizDto, enterpriseCar);
        enterpriseCarHandoverCreateDto.setEnterpriseId(orderEnterpriseDto.getEnterpriseId());
        enterpriseCarHandoverCreateDto.setType(EnterpriseCarHandoverTypeEnum.DELIVERY.getValue());
        if (!enterpriseCarHandoverService.createCarhandover(enterpriseCarHandoverCreateDto)) {
            logger.error("交车异常，订单({})车辆({})新增车辆交接异常", orderCode, vin);
            throw new BizException("交车异常");
        }

        //修改企业订单
        List<EnterpriseCarDto> enterpriseCarDtoList = enterpriseCarService.getEnterpriseCar(orderCode, EnterpriseCarStateEnum.UNDELIVERY);
        if (enterpriseCarDtoList.size() == 1
                && !orderEnterpriseService.modifyState(orderCode, EnterpriseStateEnum.UNDELIVERY, EnterpriseStateEnum.UNHIRE)) {
            logger.error("交车异常，订单({})修改企业订单异常", orderCode);
            throw new BizException("交车异常");
        }

        //修改订单车辆信息
        EnterpriseCarModifyDto enterpriseCarModifyDto = Convert.toEnterpriseCarModifyDto(orderEnterpriseDeliveryCreateBizDto, enterpriseCar);
        if (!enterpriseCarService.modifyDelivery(enterpriseCarModifyDto)) {
            logger.error("交车异常，订单({})车辆({})修改订单车辆信息异常", orderCode, vin);
            throw new BizException("交车异常");
        }

        // 新增订单流转信息
        if (enterpriseCarDtoList.size() == 1) {
            enterpriseStateFlowService.create(Convert.toEnterpriseStateFlowCreateDto(orderCode, orderEnterpriseDeliveryCreateBizDto));
        }
        return true;
    }


}
